package com.ouroboroswiki.core.content.markup.processor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.w3c.dom.Element;

import com.ouroboroswiki.core.ContentPath;
import com.ouroboroswiki.core.ContentUtil;

public abstract class AbstractExternalContentMarkupHandler implements MarkupHandler {

	public static final String ATTRIBUTE_PATH 		= "path";
	public static final String ATTRIBUTE_REPOSITORY = "repo";
	public static final String ATTRIBUTE_MODE 		= "mode";
	public static final String ATTRIBUTE_ID 		= "id";
	
	public static final String MODE_REPLACE			= "replace";
	public static final String MODE_ABSOLUTE		= "absolute";
	public static final String MODE_APPEND			= "append";
	public static final String MODE_ABSOLUTE_REPLACE= "absoluteReplace";
	
	public static final String MODE_DEFAULT 		= MODE_ABSOLUTE;
	

	protected ContentPath buildPathFromContext(Element e, ContentPath path) {
		String childPathString = e.getAttribute(ATTRIBUTE_PATH);
		
		String mode = e.getAttribute(ATTRIBUTE_MODE);
		String repositoryString = e.getAttribute(ATTRIBUTE_REPOSITORY);

		if( mode == null || mode.length() == 0 ) {
			mode = MODE_DEFAULT;
		}
		List<ContentPath> childPaths;
		if( e.hasAttribute(ATTRIBUTE_PATH) ) {
			childPaths = ContentUtil.listFromString(childPathString);
			if( MODE_APPEND.equals( mode ) ) {
				// put our context on top of this
				ArrayList<ContentPath> paths = new ArrayList<ContentPath>();
				ContentPath p = path;
				while( p != null ) {
					paths.add( p );
					//TODO:these aren't guaranteed to be only children
					p = p.getOnlyChild();
				}
				for( int i=paths.size()-1; i>0; ) {
					i--;
					ContentPath o = paths.get( i );
					childPaths = Arrays.asList(
							new ContentPath( 
									o.getName(), 
									childPaths,
									o.isContextualBreak() 
							)
					);
				}
				
			}
		} else {
			if( MODE_ABSOLUTE.equals( mode ) || MODE_ABSOLUTE_REPLACE.equals( mode ) ) {
				childPaths = Arrays.asList(path.getBasePath());
			} else {
				childPaths = Arrays.asList(path);				
			}
		}
		String[] repo;
		for( int i=0; i<childPaths.size(); i++ ) {
			ContentPath childPath = childPaths.get(i);
			List<ContentPath> basePaths;
			if( MODE_REPLACE.equals( mode ) ) {
				basePaths = childPath.getNextContext();
			} else if( MODE_ABSOLUTE_REPLACE.equals( mode ) ) {
				// remove all but the last context
				basePaths = childPath.getBasePaths();				
			} else {
				basePaths = new ArrayList<ContentPath>(1);
				basePaths.add(childPath);
			}
			ContentPath newPath;
			if( repositoryString != null && repositoryString.length() > 0 ) { 
				//TODO this splitting isn't correct
				repo = repositoryString.split("\\.");
				// append the repo
				newPath = new ContentPath(repo[0], basePaths, true);
				for( int j=1; j<repo.length; j++ ) {
					newPath = new ContentPath(repo[j], newPath, false);
				}
			} else {
				if( basePaths.size() > 1 ) {
					ContentUtil.merge(basePaths);
				}
				if( basePaths.size() == 1 ) {
					newPath = basePaths.get(0);
				} else {
					throw new IllegalArgumentException("too many paths "+basePaths.size());
				}
			}
			childPaths.set(i, newPath);
		}
		ContentUtil.merge(childPaths);
		return childPaths.get(0);

	}
}
